type fetchMethod =
  | "GET"
  | "HEAD"
  | "PATCH"
  | "POST"
  | "PUT"
  | "DELETE"
  | "CONNECT"
  | "OPTIONS"
  | "TRACE"
  | "get"
  | "head"
  | "patch"
  | "post"
  | "put"
  | "delete"
  | "connect"
  | "options"
  | "trace";
const _fetch = <T>(
  url: string,
  options?: {
    method?: fetchMethod;
    body?: BodyInit;
  }
) => {
  const isLoading = useState<boolean>("isLoading");
  isLoading.value = true;
  return $fetch<T>(`${useRuntimeConfig().public.apiUrl}${url}`, {
    headers: {
      "Content-Type": "application/json",
      Authorization: `Bearer ${useCookie("token").value}`,
    },
    method: options?.method,
    body: options?.body,
  })
    .then((r) => {
      const resp = r as ApiResp<T>;
      if (resp.code !== 0) {
        const toadMsg = useState<string>("toadMsg");
        toadMsg.value = resp.msg;
        return;
      }
      return Promise.resolve(resp.data);
    })
    .finally(() => {
      isLoading.value = false;
    });
};

export const $get = <T>(url: string) => _fetch<T>(url);
export const $post = <T>(url: string, body?: any) =>
  _fetch<T>(url, { method: "POST", body: JSON.stringify(body) });
export const $put = <T>(url: string, body?: any) =>
  _fetch<T>(url, { method: "PUT", body: JSON.stringify(body) });
export const $patch = <T>(url: string, body?: any) =>
  _fetch<T>(url, { method: "PATCH", body: JSON.stringify(body) });
export const $delete = <T>(url: string) => _fetch<T>(url, { method: "DELETE" });
